package com.incross.dawin.views;

import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.HttpResponse;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.incross.dawin.DawinConfig;
import com.incross.dawin.http.BKConnectionManager;
import com.incross.dawin.http.parser.BKAdInfoParser;
import com.incross.dawin.http.parser.IconInfoParser;
import com.incross.dawin.objects.AdInfos;
import com.incross.dawin.util.BKErrorHandler;
import com.incross.dawin.util.BKImageDownloader;
import com.incross.dawin.util.BKLog;
import com.incross.dawin.util.CommonUtils;
import com.incross.dawin.views.BKDialog.OnDialogStateListener;
import com.incross.dawin.views.BKVideoPlayer.OnVideoErrorListener;

public class DawinAdPlayer extends LinearLayout implements BKConnectionManager.RequestStateListener, BKDialog.OnDialogStateListener {
	private static final int REQUEST_START = 1000;
	private static final int REQUEST_QUARTER = 1100;
	private static final int REQUEST_QUEARTER2 = 1200;
	private static final int REQUEST_QUEARTER3 = 1300;
	private static final int REQUEST_FINISHED = 1400;
	private static final int REQUEST_SKIP = 1500;
	private static final int REQUEST_ERROR = 1600;
	private static final int REQUEST_AD_INFOS = 1700;
	private static final int REQUEST_CHARGE = 1900;
	private static final int REQUEST_PHONE_CLICK = 2000;
	private static final int REQUEST_SEND_TAG = 2100;
	
	public static final int ICON_CLICK_STOP = 123;
	public static final int ICON_CLICK_PAUSE = 456;
	
	public static final int BROWSER_MODE_INTERNEL = 10000;
	public static final int BROWSER_MODE_WEBVIEW = 20000;
	public static final int WEBVIEW_FULL = 21000;
	public static final int WEBVIEW_DIALOG = 22000;
	
	public static final int AD_FINISH_ACTION_COMPLETE = 30000;
	public static final int AD_FINISH_ACTION_SKIP = 31000;
	public static final int AD_FINISH_ACTION_SCREEN_CLICK = 32000;
	public static final int AD_FINISH_ACTION_BUTTON_CLICK = 33000;
	public static final int AD_FINISH_INCOMING_CALL = 34000;
	public static final int AD_FINISH_NO_APPLICABLE_AD = 35000;
	public static final int AD_FINISH_BACK_KEY_PRESSED = 35100;
	public static final int AD_FINISH_AFTER_CLICKVIEWER = 35200;
	public static final int AD_FINISH_OTHER_REASON = 35300;
	//
	public static final int AD_FINISH_NETWORK_DISCONNECTED = 36000;
	public static final int AD_FINISH_AD_INFO_RECEIVE_FAIL = 36100;
	public static final int AD_FINISH_OTHER_ERROR = 36200;
	
	private static final int QUARTER_CHECK_TIMER = 10;
	private static final int CHARGE_TIMER = 11;
	private static final int SKIP_TIMER = 12;
	
	private static final int MESSAGE_SHOW_SKIP = 100;
	
	private static final int CALL_STATE_IDLE = 40000;
	private static final int CALL_STATE_INCOMING = 41000;
	private static final int CALL_STATE_OUTGOING = 42000;
	
	// 송출기 응답없을시 로그 수집 url
	private static final String ADINFO_ERROR_LOG_REL = "http://adm.dawin.tv/common/dawinErrorLog.do?eCd=08010309&eUrl=";
	private static final String ADINFO_ERROR_LOG_DEV = "http://112.169.59.42:9090/common/dawinErrorLog.do?eCd=08010309&eUrl=";
	
	private int mCurrentOrientation;
	
	private int mDawinServerType = DawinConfig.DAWIN_SERVER_REAL;
	
	private final int MAX_RETRY_COUNT = 2;
	private final String AD_INFO_URL = "http://ads.dawin.tv/imp";//"http://112.169.59.43/imp";
	private final String AD_INFO_TEST_URL = "http://112.169.59.43/imp";
	
	private JSONObject mAdInfoParameter;
	
	private Context mContext;
	private AttributeSet mAttributeSet;
	private int mDefStyle;
	
	private int mAdDuration;
	
	private int mDialogMarginRate = 5;
	
	private RelativeLayout mVideoLayout;
	private BKVideoPlayer mVideoPlayer;
	
	private ImageButton mFacebookButton, mTwitterButton, mMe2DayButton, mSkipButton, mSkipDescriptionButton;
	private ImageButton mCallButton, mMapButton, mEventButton, mDownloadButton;
	
	private LinearLayout mSnsLayout, mEventLayout, mCallLayout, mDownloadLayout, mMapLayout, mSkipLayout;
	
	
	private OnPlayFinishListener mPlayFinishListener;
	private OnErrorListener mErrorListener;
	private OnPreparedListener mPreparedListener;
	
	private BKConnectionManager mConnectionManager;
	
	private ProgressBar mProgress;
	
	private AdInfos mAdInfos;
	private BKImageDownloader mImageDownloader;
	private int mQuarter, mQuarter2, mQuarter3;
	private int mCurrentQuarter = 1;
	private int mLastSendedTag = 0;
	private MediaController mMediaController;
	private boolean mIsStartTagSended = false;
	
	private boolean mIsVideoClickProcessing = false;
	
	// flags for call(incoming outgoing)
	private int mCurrentCallState = CALL_STATE_IDLE;
	
	
	private int mButtonSize = 60;
	private int mSkipButtonWidth = 150;
	private int mSkipDescWidth = 468;
	private int mSkipButtonHeight = 156;
	
	private int mParentWidth, mParentHeight;
	
	private boolean mIsClickviewerShown = false;
	private boolean mIsOnPauseCalled = false;
	
	
	private int mAdInfoRetryCount = 0;
	private int mChargeTagRetryCount = 0;
	
	private boolean mIsChargeTagSendSucceed = false;
	
	private int mDeviceDensity;
	
	private BKErrorHandler mErrorHandler;
	
	private int mChargeTime = 0;
	
	private String xmlString;
	
	// 광고 요청 url 저장 : 광고정보 수신 실패시 서버에 보내는 용도.
	private String mAdinfoRequestUrl = "";
	
	// skip timer.
	private Timer mSkipTimer;
	private TimerTask mSkipTimerTask;
	private boolean mIsSkipTimerRunning = false;
	
	// charge timer
	private Timer mChargeTimer;
	private TimerTask mChargeTimerTask;
	private boolean mIsChargeTimerRunning = false;
	
	// quarter check timer
	private Timer mQuarterTimer;
	private TimerTask mQuarterTimerTask;
	private boolean mIsQuarterTimerRunning = false;
	
	private int mTimerPeriod = 100;
	private int mTimerDelay = 0;
	
	
	// 15초 광고인 경우 과금태그를 광고가 끝나는 시점에 호출하기 위해 체크
	private boolean mIsQuarterMinAd = false;
	
	// T store 설치여부 저장하는 flag
	private boolean mIsTstoreInstalled = false;
	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch(msg.what) {
				case MESSAGE_SHOW_SKIP:
					if(mSkipButton != null) {
						mSkipDescriptionButton.setVisibility(View.GONE);
						mSkipButton.setVisibility(View.VISIBLE);
					}
					break;
			}
		}
	};
	
	private void initTelephonyManager() {
		TelephonyManager tManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 
		tManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
	}
	
	private PhoneStateListener phoneStateListener = new PhoneStateListener() {
		public void onCallStateChanged(int state, String incomingNumber) {// 전화 수신 반응.
			 // 착신 전화 번호를 받는다.
			 switch (state) {
				 case TelephonyManager.CALL_STATE_IDLE :  
					 break; // 폰이 울리거나 통화중이 아님.o
				 case TelephonyManager.CALL_STATE_RINGING :
					 mCurrentCallState = CALL_STATE_INCOMING;
					 
					 if(mVideoPlayer != null && mVideoPlayer.isPlaying()) {
						 mVideoPlayer.pause();
					 }
					 if(mPlayFinishListener != null) {
						 mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_INCOMING_CALL);
					 }
					 destroy();
					 
					 break; // 폰이 울린다.
				 case TelephonyManager.CALL_STATE_OFFHOOK :
					 break; // 폰이 현재 통화 중.
				 default:      
					 break;
			 }
		 }
	};
	
	
	
	
	
	public interface OnAdViewStateListener {
		public abstract void onPrepared(MediaPlayer mp);
		public abstract void onHttpRequestError();
	}
	
	
	public interface OnPlayFinishListener {
		public abstract void onPlayFinished(DawinAdPlayer dawinPlayer, int finishedBy);
	}
	
	public interface OnPreparedListener {
		public abstract void onPrepared();
	}
	
	/**
	 * same as MediaPlayer.OnErrorListener
	 */
	public interface OnErrorListener {
		public abstract void onError(MediaPlayer mp, int what, int extra);
	}
	
	public DawinAdPlayer(Context context) {
		super(context);
		mContext = context;
		init();
		setViews();
	}
	
	public DawinAdPlayer(Context context, AttributeSet attrs) {
		super(context, attrs);
		mAttributeSet = attrs;
		mContext = context;
		init();
		setViews();
	}
	
	public DawinAdPlayer(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs);
		mAttributeSet = attrs;
		mDefStyle = defStyle;
		mContext = context;
		init();
		setViews();
	}
	
	public void setDawinServerType(int type) {
		if(type != DawinConfig.DAWIN_SERVER_REAL && type != DawinConfig.DAWIN_SERVER_TEST) return;
		mDawinServerType = type;
	}
	
	private void init() {
		mIsTstoreInstalled = CommonUtils.isPackageInstalled(mContext, "com.skt.skaf.A000Z00040");
		
		initTelephonyManager();
		
		mConnectionManager = new BKConnectionManager(mContext);
		mImageDownloader = new BKImageDownloader(mContext);
		mConnectionManager.setOnConnectionStateListener(this);
		CommonUtils.getDeviceType(mContext);
		mErrorHandler = new BKErrorHandler(mContext);
		
		mDeviceDensity = CommonUtils.getDensity(mContext);
		
		if(mDeviceDensity == CommonUtils.DENSITY_LDPI) { // ldpi
			BKLog.i("-- LDPI");
//			mButtonSize = 50;
//			mSkipButtonWidth = 75;
//			mSkipButtonHeight = 78;
//			mSkipDescWidth = 234;
			mButtonSize = 40;
			mSkipButtonWidth = 60;
			mSkipButtonHeight = 62;
			mSkipDescWidth = 187;
		} else if(mDeviceDensity == CommonUtils.DENSITY_MDPI) { // mdpi
			BKLog.i("-- MDPI");
//			mButtonSize = 60;
//			mSkipButtonWidth = 90;
//			mSkipButtonHeight = 94;
//			mSkipDescWidth = 282;
			mButtonSize = 48;
			mSkipButtonWidth = 72;
			mSkipButtonHeight = 75;
			mSkipDescWidth = 226;
		} else if(mDeviceDensity == CommonUtils.DENSITY_HDPI) { // hdpi
			BKLog.i("-- HDPI");
//			mButtonSize = 70;
//			mSkipButtonWidth = 105;
//			mSkipButtonHeight = 109;
//			mSkipDescWidth = 327;
			mButtonSize = 56;
			mSkipButtonWidth = 87;
			mSkipButtonHeight = 87;
			mSkipDescWidth = 262;
		} else if(mDeviceDensity == CommonUtils.DENSITY_XHDPI) { // xhdpi
			BKLog.i("-- XHDPI");
			// 버튼 사이즈 80%로 줄임
//			mButtonSize = 100;
//			mSkipButtonWidth = 150;
//			mSkipButtonHeight = 156;
//			mSkipDescWidth = 468;
			mButtonSize = 80;
			mSkipButtonWidth = 120;
			mSkipButtonHeight = 125;
			mSkipDescWidth = 374;
		} else if(mDeviceDensity == CommonUtils.DENSITY_XXHDPI) { // xxdpi
			// 25% higher than xhdpi
			mButtonSize = 100;
			mSkipButtonWidth = 150;
			mSkipButtonHeight = 156;
			mSkipDescWidth = 468;
		} else if(mDeviceDensity == CommonUtils.DENSITY_SXHDPI) { // sxhdpi
			// 20% higher than xxhdpi
			mButtonSize = 120;
			mSkipButtonWidth = 180;
			mSkipButtonHeight = 187;
			mSkipDescWidth = 562;
		}
		
		downloadImageIfNotExists();
	}
	
	private void downloadImageIfNotExists() {
		if(!mImageDownloader.isExists(DawinConfig.IMG_BACK_URL)) {
			mImageDownloader.download(DawinConfig.IMG_BACK_URL);
		}
		
		if(!mImageDownloader.isExists(DawinConfig.IMG_BG_NOR_URL)) {
			mImageDownloader.download(DawinConfig.IMG_BG_NOR_URL);
		}
		
		if(!mImageDownloader.isExists(DawinConfig.IMG_BG_SEL_URL)) {
			mImageDownloader.download(DawinConfig.IMG_BG_SEL_URL);
		}
		
		if(!mImageDownloader.isExists(DawinConfig.IMG_CLOSE_URL)) {
			mImageDownloader.download(DawinConfig.IMG_CLOSE_URL);
		}
		
		if(!mImageDownloader.isExists(DawinConfig.IMG_FORWARD_URL)) {
			mImageDownloader.download(DawinConfig.IMG_FORWARD_URL);
		}
		
		if(!mImageDownloader.isExists(DawinConfig.IMG_REFRESH_URL)) {
			mImageDownloader.download(DawinConfig.IMG_REFRESH_URL);
		}
		
		if(!mImageDownloader.isExists(DawinConfig.IMG_SEND_URL)) {
			mImageDownloader.download(DawinConfig.IMG_SEND_URL);
		}
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	
	@Override
	protected void onSizeChanged (int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		BKLog.d("====================on size changed=============================");
		BKLog.d("w : " + w + ", h : " + h + ", oldw : " + oldw + ", oldh : " + oldh);
		
		if(mVideoPlayer != null) {
			int orientation;
			if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
				orientation = Configuration.ORIENTATION_PORTRAIT;
			} else {
				orientation = Configuration.ORIENTATION_LANDSCAPE;
			}
			
			mVideoPlayer.setParentViewSize(orientation, w, h);
//			mVideoPlayer.changeDimension();
		}
		
		
	}
	
	@Override
	protected void onDraw (Canvas canvas) {
		super.onDraw(canvas);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		
		mCurrentOrientation = CommonUtils.getOrientation(mContext);
		DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
	    int width = displayMetrics.widthPixels;
    	int height = displayMetrics.heightPixels;
    	
    	int rightMargin = width - r;
    	int topMargin = t;
    	int bottomMargin = height - b;
    	int leftMargin = l;
    	
    	mParentWidth = width - rightMargin - leftMargin;
    	mParentHeight = height - topMargin - bottomMargin;
    	if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_LANDSCAPE && !mVideoPlayer.isParentSizeAvailable(Configuration.ORIENTATION_LANDSCAPE)) {
    		mVideoPlayer.setParentViewSize(Configuration.ORIENTATION_LANDSCAPE, mParentWidth, mParentHeight);
    	}
    	
    	if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT && !mVideoPlayer.isParentSizeAvailable(Configuration.ORIENTATION_PORTRAIT)) {
    		mVideoPlayer.setParentViewSize(Configuration.ORIENTATION_PORTRAIT, mParentWidth, mParentHeight);
    	}
    	
		/*BKLog.d("Parent width : " + mParentWidth + "px, parent height : " + mParentHeight + "px");
		BKLog.d("display width : " + width + ", display height : " + height);
		mVideoPlayer.changeDimension();*/
	}
	
	/*public void changeLayoutMode(int mode) {
		mVideoPlayer.changeVideoMode(mode);
	}*/
	
	
	/**
	 * must call onResume at activity's onResume();
	 */
	public void onResume() {
		// finish Activity when call event
		BKLog.e("onResume dawinadplayer");
		if(mCurrentCallState == CALL_STATE_INCOMING || mCurrentCallState == CALL_STATE_OUTGOING) {
			BKLog.w("Call finish");
			initializeVideoView();
			if(mPlayFinishListener != null) {
				 mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_INCOMING_CALL);
			}
		} else if(mIsClickviewerShown) {
			initializeVideoView();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_CLICKVIEWER);
			}
		} else if(mIsOnPauseCalled) {
			BKLog.e("isPauseCalled!!");
			initializeVideoView();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
		}
	}
	
	private void setViews() {
		LinearLayout mainLayout = new LinearLayout(mContext);
		mainLayout.setOrientation(LinearLayout.VERTICAL); 
		mainLayout.setBackgroundColor(Color.parseColor("#000000"));
		
		LinearLayout.LayoutParams mainParam = 
				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
		
		mainParam.setMargins(0, 0, 0, 0);
		
		mVideoLayout = new RelativeLayout(mContext);
		
		RelativeLayout.LayoutParams buttonLayoutParam = 
				new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		buttonLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		buttonLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		
		
		
		mVideoPlayer = new BKVideoPlayer(mContext);
		
		RelativeLayout.LayoutParams videoParam = 
				new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		videoParam.setMargins(0, 0, 0, 0);
		videoParam.addRule(RelativeLayout.CENTER_IN_PARENT);
		
		
		mVideoLayout.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null && !mIsVideoClickProcessing) {
					if(mAdInfos.getVideoClickTracking() != null && !mAdInfos.getVideoClickTracking().equals("")) {
//						BKLog.e("ontouch");
						mIsVideoClickProcessing = true;
						lockClickEvents(false);
						cancelAllTimer();
						if(mVideoPlayer.canPause()) {
							mVideoPlayer.pause();
						}
						showProgress();
						handleScreenClick(mAdInfos.getVideoClickTracking() + getActionButtonParameter(), mAdInfos.getVideoclickThrough());
					}
				}
			}
		});
		
//		mVideoLayout.setOnTouchListener(new OnTouchListener() {
//			
//			@Override
//			public boolean onTouch(View v, MotionEvent event) {
//				if(mAdInfos != null && !mIsVideoClickProcessing) {
//					if(mAdInfos.getVideoClickTracking() != null && !mAdInfos.getVideoClickTracking().equals("")) {
////						BKLog.e("ontouch");
//						mIsVideoClickProcessing = true;
//						lockClickEvents(false);
//						cancelAllTimer();
//						if(mVideoPlayer.canPause()) {
//							mVideoPlayer.pause();
//						}
//						showProgress();
//						handleScreenClick(mAdInfos.getVideoClickTracking() + getActionButtonParameter(), mAdInfos.getVideoclickThrough());
//					}
//				}
//				
//				return false;
//			}
//		});
		
		mVideoPlayer.setOnVideoErrorListener(new OnVideoErrorListener() {
			
			@Override
			public void onVideoError(MediaPlayer mp, int errorCode) {
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=9");
				}
				destroy();
				Log.e(getClass().getName(), "DawinAdPlayer video player error.. finish dawin ad player");
				
			}
		});
		
		mSnsLayout = new LinearLayout(mContext);
		mSnsLayout.setOrientation(LinearLayout.HORIZONTAL);
		mSnsLayout.setVisibility(View.GONE);
		
		mEventLayout = new LinearLayout(mContext);
		mEventLayout.setVisibility(View.GONE);
		
		mCallLayout = new LinearLayout(mContext);
		mCallLayout.setVisibility(View.GONE);
		
		mDownloadLayout = new LinearLayout(mContext);
		mDownloadLayout.setVisibility(View.GONE);
		
		mMapLayout = new LinearLayout(mContext);
		mMapLayout.setVisibility(View.GONE);
		
		mSkipLayout = new LinearLayout(mContext);
		mSkipLayout.setVisibility(View.GONE);
		
		RelativeLayout.LayoutParams buttonParams = 
				new RelativeLayout.LayoutParams(mButtonSize, mButtonSize);
		buttonParams.setMargins(0, 0, 0, 0);
		
		RelativeLayout.LayoutParams skipLayoutParam = 
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		skipLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		skipLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		
		mVideoLayout.addView(mVideoPlayer, videoParam);
		mVideoLayout.addView(mSnsLayout, buttonLayoutParam);
		mVideoLayout.addView(mEventLayout, buttonLayoutParam);
		mVideoLayout.addView(mCallLayout, buttonLayoutParam);
		mVideoLayout.addView(mDownloadLayout, buttonLayoutParam);
		mVideoLayout.addView(mMapLayout, buttonLayoutParam);
		mVideoLayout.addView(mSkipLayout, skipLayoutParam);
		
		
		
		// initialize sns buttons.
		mMe2DayButton = new ImageButton(mContext);
		mMe2DayButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.ME2DAY, mAdInfos.getTrackingUrl(AdInfos.ME2DAY) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.ME2DAY));
					
				}
			}
		});
		
		mFacebookButton = new ImageButton(mContext);
		mFacebookButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.FACEBOOK, mAdInfos.getTrackingUrl(AdInfos.FACEBOOK) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.FACEBOOK));
				}
			}
		});
		
		mTwitterButton = new ImageButton(mContext);
		mTwitterButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.TWITTER, mAdInfos.getTrackingUrl(AdInfos.TWITTER) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.TWITTER));
				}
			}
		});
		
		// init other buttons
		mCallButton = new ImageButton(mContext);
		mCallButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.CALL, mAdInfos.getClickThrough(AdInfos.CALL), null);
				}
				
			}
		});
		
		mMapButton = new ImageButton(mContext);
		mMapButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.MAP, mAdInfos.getTrackingUrl(AdInfos.MAP) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.MAP));
				}
				
			}
		});
		
		mEventButton = new ImageButton(mContext);
		mEventButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.EVENT, mAdInfos.getTrackingUrl(AdInfos.EVENT) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.EVENT));
				}
				
			}
		});
		
		mDownloadButton = new ImageButton(mContext);
		mDownloadButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelAllTimer();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
						mVideoPlayer.release();
						mIsClickviewerShown = true;
					}
					showProgress();
					/* 20130806 예외적으로 Download Action 클릭에서만 리다이렉트 시키지 않는 것으로 서버팀과 협의함
					  기획팀의 만행으로(만들어준 테스트 앱 확인 안해봄) 기존에는 클릭뷰어에서 처리하던 것을 클릭뷰어를 
					  띄우지 않고 처리하는 것으로 변경함 */
					// 태그 전송용 url
					String appTagUrl = mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter();
					mConnectionManager.sendRequest(REQUEST_SEND_TAG, appTagUrl, null);
					
					// 스토어 연결에 사용할 url
					// 2013.09.30 화면클릭시에도 다운로드가 가능하도록 하기위해서 코드 중복배제를 위해 메소드로 분리
					downloadApp(mAdInfos.getClickThrough(AdInfos.DOWNLOAD).trim());
					
//					기존 클릭뷰어로 보내던 동작 주석처리
//					handleActionClick(AdInfos.DOWNLOAD, mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.DOWNLOAD));
				}
				
			}
		});
		
		
		// Add sns buttons to sns layout.
		mSnsLayout.addView(mFacebookButton, buttonParams);
		mSnsLayout.addView(mTwitterButton, buttonParams);
		mSnsLayout.addView(mMe2DayButton, buttonParams);
		
		// Add call button to call layout
		mCallLayout.addView(mCallButton, buttonParams);
		
		// Add download button to download layout
		mDownloadLayout.addView(mDownloadButton, buttonParams);
		
		// Add map button to map layout
		mMapLayout.addView(mMapButton, buttonParams);
		
		// Add event button to event layout
		mEventLayout.addView(mEventButton, buttonParams);
		
		mSkipButton = new ImageButton(mContext);
		mSkipButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					showProgress();
					if(mVideoPlayer.canPause()) {
						mVideoPlayer.pause();
					}
					cancelAllTimer();
					
					mConnectionManager.sendRequest(REQUEST_SKIP, mAdInfos.getSkipTag(), null);
				}
			}
		});
		
		mSkipDescriptionButton = new ImageButton(mContext);
		
		mFacebookButton.setVisibility(View.GONE);
		mTwitterButton.setVisibility(View.GONE);
		mMe2DayButton.setVisibility(View.GONE);
		mSkipButton.setVisibility(View.GONE);
		mSkipDescriptionButton.setVisibility(View.VISIBLE);
		mDownloadButton.setVisibility(View.GONE);
		mMapButton.setVisibility(View.GONE);
		mCallButton.setVisibility(View.GONE);
		mEventButton.setVisibility(View.GONE);
		
		
		
		LinearLayout.LayoutParams skipButtonParam = 
				new LinearLayout.LayoutParams(mSkipButtonWidth, mSkipButtonHeight);
		
		LinearLayout.LayoutParams skipDescriptionButtonParam = 
			new LinearLayout.LayoutParams(mSkipDescWidth, mSkipButtonHeight);
		
		
		mSkipLayout.addView(mSkipButton, skipButtonParam);
		mSkipLayout.addView(mSkipDescriptionButton, skipDescriptionButtonParam);
		
		
		// Progress bar
		mProgress = new ProgressBar(mContext, null, android.R.attr.progressBarStyle);
		mProgress.setVisibility(View.GONE);
		RelativeLayout.LayoutParams progressParam = 
				new RelativeLayout.LayoutParams(mButtonSize, mButtonSize);
		progressParam.addRule(RelativeLayout.CENTER_IN_PARENT);
		mVideoLayout.addView(mProgress, progressParam);
		
		
		
		mVideoPlayer.setOnVideoErrorListener(new BKVideoPlayer.OnVideoErrorListener() {
			
			@Override
			public void onVideoError(MediaPlayer mp, int errorCode) {
				
				
				if(mVideoPlayer != null) {
					mVideoPlayer.pause();
					destroy();
				}
				
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
				}
				
				if(mErrorListener != null) {
					mErrorListener.onError(mp, errorCode, 0);
				}
				
			}
		});
				
		
		mVideoPlayer.setOnVideoStartListener(new BKVideoPlayer.OnVideoStartListener() {
			
			@Override
			public void onVideoStarted() {
				// Handler에서 보내는 메세지.. 
				BKLog.i("onVideoStarted =============>");
				try {
					if(mAdInfos != null) {
						if(!mIsStartTagSended) {
							mIsStartTagSended = true;
							mConnectionManager.sendRequest(REQUEST_START, mAdInfos.getStartTag(), null);
						}
						hideProgress();
						if(!mIsChargeTagSendSucceed) {
							if(!mIsQuarterMinAd) {
								BKLog.e("ChargeTime : " + mChargeTime);
								int chargeTimeDelay = (int) (mChargeTime / 0.8);
								startTimer(CHARGE_TIMER, chargeTimeDelay, mTimerPeriod);
							}
							
						}
						startTimer(SKIP_TIMER, mTimerDelay, mTimerPeriod);
						startTimer(QUARTER_CHECK_TIMER, mTimerDelay, mTimerPeriod);
						
						showActionLayout();
					}
					
				} catch(Exception e) {
					// 잘못된 상황임.
					
				}
				
				
			}
		});
		
		
		mVideoPlayer.setOnPlayFinishListener(new BKVideoPlayer.OnPlayFinishListener() {
			@Override
			public void onPlayFinished(MediaPlayer mp) {
				mVideoPlayer.pause();
				mVideoPlayer.stop();
				mVideoPlayer.release();
				showProgress();
				// 과금테그 전송여부 확인
				if(mIsChargeTagSendSucceed) {
					if(mAdInfos != null) {
						mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
					} else {
						hideProgress();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
						}
					}
				} else {
					if(mIsQuarterMinAd) {
						if(mAdInfos != null) {
							mConnectionManager.sendRequest(REQUEST_CHARGE, mAdInfos.getChargeTag(), null);
						} else {
							hideProgress();
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
							}
						}
					} else {
						if(mAdInfos != null) {
							mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
						} else {
							hideProgress();
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
							}
						}
					}
				}
			}
		});
		
		DawinAdPlayer.this.addView(mVideoLayout, mainParam);
	}
	
	/**
	 * 2013.09.30 화면클릭으로 다운로드가 가능하도록 하기위해 변경함.
	 * 광고에서 지정한 앱 다운로드시에 사용함.
	 * @param downloadUrl : T-store 또는 Android 지원하는 형식의 주소 사용.
	 * @return
	 */
	public boolean downloadApp(String downloadUrl) {
		if(downloadUrl == null || downloadUrl.equals("")) return false;
		// 20131001 어쨋던 외부로 나간 후 종료하는 것이므로, 이 경우 클릭뷰어 종료로 처리함.(기존 다운로드가 그렇게 처리중이었음)
		mIsClickviewerShown = true;
		
		if(downloadUrl.contains("tstore://")) {
			BKLog.e("T store app!! : " + downloadUrl);
			String key = downloadUrl.substring(9);
			if(mIsTstoreInstalled) {
				Intent intent = new Intent();
				intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
				intent.setClassName("com.skt.skaf.A000Z00040", "com.skt.skaf.A000Z00040.A000Z00040");
				intent.setAction("COLLAB_ACTION");
				intent.putExtra("com.skt.skaf.COL.URI", key.getBytes());
				intent.putExtra("com.skt.skaf.COL.REQUESTER", "A000Z00040");
				mContext.startActivity(intent);
			} else {
				/* 20130809 기획팀은 앱 설치가 되지 않은 경우 설치 안내페이지로 연결해달라는 말에 동의를 했으나 자세한 설명을 해주지 않았음에도 불구하고 이렇게 되는 것이 아니라며 또다시 내용을 수정함
				 * 현재 설치 안내페이지에서 http://tsto.re/앱정보 형식으로 외부 브라우저로 연결하도록 변경함.*/
				BKLog.e("tstore not installed. go to install guide page.");
				String[] splitString = downloadUrl.split("PRODUCT_VIEW/");
				String downloadInfo = (splitString[1].split("/"))[0];
				BKLog.e("download info : " + downloadInfo);
				
				Intent i = new Intent(Intent.ACTION_VIEW);
				Uri u = Uri.parse("http://tsto.re/" + downloadInfo);
				i.setData(u); 
				mContext.startActivity(i);
			}   
			BKLog.e(key);
			
			
		} else if(downloadUrl.contains("market://")) {
			BKLog.e("google market app!!" + downloadUrl);
			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.addCategory(Intent.CATEGORY_DEFAULT);
			intent.setData(Uri.parse(downloadUrl));
			mContext.startActivity(intent);
		} else {
			// 예외상황이라서 기타 오류로 종료 처리.
			mIsClickviewerShown = false;
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			}
			return false;
		}
		
		return true;
	}
	
	
	
	public void initTimers() {
		// skip timer initialize
		if(mSkipTimer == null) {
			mSkipTimer = new Timer();
		} else {
			mSkipTimer.cancel();
			mSkipTimer.purge();
			if(mSkipTimerTask != null) {
				mSkipTimerTask.cancel();
			}
		}
		
		if(mSkipTimerTask == null) {
			mSkipTimerTask = new TimerTask() {
				@Override
				public void run() {
					try {
						
						if(mVideoPlayer != null && mVideoPlayer.isPlaying() && mVideoPlayer.getCurrentPosition() > (mAdInfos != null?mAdInfos.getIconShowTime(AdInfos.SKIP) : 5000)) {
							mHandler.sendEmptyMessage(MESSAGE_SHOW_SKIP);
							cancelTimer(SKIP_TIMER);
						}
					} catch(Exception e) {
						e.printStackTrace();
					}
				}
			};
		}
		
		// charge timer initialize
		if(mChargeTimer == null) {
			mChargeTimer = new Timer();
		} else {
			mChargeTimer.cancel();
			mChargeTimer.purge();
			if(mChargeTimerTask != null) {
				mChargeTimer.cancel();
			}
		}
		
		if(mChargeTimerTask == null) {
			mChargeTimerTask = new TimerTask() {
				@Override
				public void run() {
					BKLog.d("Charge Timer ----");
					try {
						if(mVideoPlayer != null && mVideoPlayer.getCurrentPosition() > mChargeTime && mVideoPlayer.isPlaying()) {
							if(mAdInfos != null) {
								mConnectionManager.sendRequest(REQUEST_CHARGE, mAdInfos.getChargeTag(), null);
							}
							cancelTimer(CHARGE_TIMER);
						}
					} catch(Exception e) {
						e.printStackTrace();
						cancelAllTimer();
					}
					
				}
			};
		}
		
		// quarter timer initialize
		if(mQuarterTimer == null) {
			mQuarterTimer = new Timer();
		} else {
			mQuarterTimer.cancel();
			mQuarterTimer.purge();
			if(mQuarterTimerTask != null) {
				mQuarterTimerTask.cancel();
			}
		}
		
		if(mQuarterTimerTask == null) {
			mQuarterTimerTask = new TimerTask() {
				@Override
				public void run() {
					try {
						if(mVideoPlayer != null && mVideoPlayer.isPlaying()) {
							if(mVideoPlayer.getCurrentPosition() > mQuarter && mVideoPlayer.getCurrentPosition() < mQuarter2) {
								if(mCurrentQuarter != 2) {
									mCurrentQuarter = 2;
									BKLog.d("Quarter2!");
									
									if(mAdInfos != null) {
										mConnectionManager.sendRequest(REQUEST_QUARTER, mAdInfos.getQuarterTag(1), null);
									}
									mLastSendedTag = 1;
								}
							} else if(mVideoPlayer.getCurrentPosition() > mQuarter2 && mVideoPlayer.getCurrentPosition() < mQuarter3) {
								if(mCurrentQuarter != 3) {
									mCurrentQuarter = 3;
									BKLog.d("Quarter3!");
									if(mAdInfos != null) {
										mConnectionManager.sendRequest(REQUEST_QUEARTER2, mAdInfos.getQuarterTag(2), null);
									}
									
									mLastSendedTag = 2;
								}
							} else if(mVideoPlayer.getCurrentPosition() > mQuarter3) {
								mCurrentQuarter = 4;
								BKLog.d("Quarter4!");
								if(mAdInfos != null) {
									mConnectionManager.sendRequest(REQUEST_QUEARTER3, mAdInfos.getQuarterTag(3), null);
								}
								mLastSendedTag = 3;
								cancelTimer(QUARTER_CHECK_TIMER);
							}
						}
					} catch(Exception e) {
						e.printStackTrace();
					}
						
				}
			};
		}
		
	}
	
	private void cancelAllTimer() {
		cancelTimer(CHARGE_TIMER);
		cancelTimer(SKIP_TIMER);
		cancelTimer(QUARTER_CHECK_TIMER);
	}
	
	private void cancelTimer(int which) {
		switch(which) {
			case CHARGE_TIMER:
				if(mIsChargeTimerRunning) {
					mIsChargeTimerRunning = false;
					if(mChargeTimer != null) {
						mChargeTimer.cancel();
						mChargeTimer.purge();
						mChargeTimer = null;
					}
					
					if(mChargeTimerTask != null) {
						mChargeTimerTask.cancel();
						mChargeTimerTask = null;
					}
				}
				
				break;
				
			case SKIP_TIMER:
				if(mIsSkipTimerRunning) {
					mIsSkipTimerRunning = false;
					if(mSkipTimer != null) {
						mSkipTimer.cancel();
						mSkipTimer.purge();
						mSkipTimer = null;
					}
					
					if(mSkipTimerTask != null) {
						mSkipTimerTask.cancel();
						mSkipTimerTask = null;
					}
				}
				
				break;
				
			case QUARTER_CHECK_TIMER:
				if(mIsQuarterTimerRunning) {
					mIsQuarterTimerRunning = false;
					if(mQuarterTimer != null) {
						mQuarterTimer.cancel();
						mQuarterTimer.purge();
						mQuarterTimer = null;
					}
					
					if(mQuarterTimerTask != null) {
						mQuarterTimerTask.cancel();
						mQuarterTimerTask = null;
					}
				}
				
				break;
		}
	}
	
	private void startTimer(int which, int delay, int period) {
		switch(which) {
			case QUARTER_CHECK_TIMER:
				if(mQuarterTimer != null && mQuarterTimerTask != null && !mIsQuarterTimerRunning) {
					mIsQuarterTimerRunning = true;
					mQuarterTimer.schedule(mQuarterTimerTask, delay, period);
				}
				break;
				
			case SKIP_TIMER:
				if(mSkipTimer != null && mSkipTimerTask != null && !mIsSkipTimerRunning) {
					mIsSkipTimerRunning = true;
					mSkipTimer.schedule(mSkipTimerTask, delay, period);
				}
				break;
				
			case CHARGE_TIMER:
				if(mChargeTimer != null && mChargeTimerTask != null && !mIsChargeTimerRunning) {
					mIsChargeTimerRunning = true;
					mChargeTimer.schedule(mChargeTimerTask, delay, period);
				}
				break;
		}
	}
	
	
	private void handleActionClick(int which, String handleInfo, String pageUrl) {
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_BUTTON_CLICK);
		}
		BKLog.e("actionClick!!! : " + handleInfo);
		mVideoPlayer.release();
		if(which == AdInfos.CALL) {
			showCallDialog(handleInfo);
		} else {
			showBrowserDialog(handleInfo, (mAdInfos != null?mAdInfos.getAdTitle():""), pageUrl);
		}
		
		
	}
	
	private void handleScreenClick(String handleInfo, String pageUrl) {
		if(mAdInfos == null) return;
		
		// 20131001 화면 클릭의 경우 클릭뷰어가 뜨던 외부 브라우저로 가던 다른 액션이 일어나므로 중복되는 코드이기 때문에 주석처리함.
//		if(mPlayFinishListener != null) {
//			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SCREEN_CLICK);
//		}
		cancelAllTimer();
		mVideoPlayer.release();
		if(mAdInfos.getActionMode() == AdInfos.ACTION_MODE_CALL) {
			showProgress();
			handleActionClick(AdInfos.CALL, mAdInfos.getVideoclickThrough(), null);
		} else if(mAdInfos.getActionMode() == AdInfos.ACTION_MODE_DOWNLOAD) {
			if(mAdInfos != null) {
				lockClickEvents(false);
				showProgress();
				// 20131001 다운로드, 전화에 한해서 클릭태그 전송시 각각의 액션에 대한 Tracking tag를 전송한다.(화면클릭태그는 실제주소를 전송해서 오류발생함)
				// 2013년 9월 30일 오후 6:33 메일 확인
				String appTagUrl = mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter();
				mConnectionManager.sendRequest(REQUEST_SEND_TAG, appTagUrl, null);
				downloadApp(mAdInfos.getVideoclickThrough());
			} else {
				
			}
		} else {
			showBrowserDialog(handleInfo, (mAdInfos != null?mAdInfos.getAdTitle() : ""), pageUrl);
		}
		
	}
	
	
	private String getActionButtonParameter() {
		String result = "";
		
		result = "&lq=" + String.valueOf(mLastSendedTag) + "&pay=" + (mIsChargeTagSendSucceed? "1": "0");
		
		return result;
	}
	
	
	private void showBrowserDialog(String path, String title, String pageUrl) {
		mIsClickviewerShown = true;
		
		if(mAdInfos.getBrowserMode().equals(AdInfos.BROWSER_MODE_DEFAULT_BROWSER)) {
			// 실제 브라우저로 넘기는 부분
			initializeVideoView();
			mIsClickviewerShown = true;
			Intent i = new Intent(Intent.ACTION_VIEW); 
			Uri u = Uri.parse(path); 
			i.setData(u); 
			mContext.startActivity(i);
		} else {
			BKDialog dialog = new BKDialog();
			dialog.setOnDialogStateListener(new OnDialogStateListener() {
				
				@Override
				public void onDialogShown() {
					BKLog.w("------- Dialog show");
				}
				
				@Override
				public void onDialogDismissed() {
					BKLog.w("------- Dialog dismissed");
				}
			});
			
//			dialog.setMargin(mDialogMarginRate);
			Intent intent = new Intent(mContext, dialog.getClass());
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_URL, path);
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_REAL_URL, pageUrl);
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_TITLE, title);
			
			((Activity) mContext).startActivityForResult(intent, BKDialog.ACTION_CLICKVIEWER);
		}
	}
	
	/*private void showBrowser(String path) {
		hideProgress();
		initializeVideoView();
		
		if(path == null) return;
		Intent i = new Intent(Intent.ACTION_VIEW); 
		Uri u = Uri.parse(path);
		i.setData(u);
		mContext.startActivity(i);
	}*/
	
	/**
	 * @deprecated
	 * this method deprecated.
	 * @param orientation : orientation to set mode
	 * @param mode : video display mode
	 * @see BKVideoView, Configuration
	 */
	public void setVideoMode(int orientation, int mode) {
		switch(orientation) {
			case Configuration.ORIENTATION_LANDSCAPE:
//				mLandscapeVideoMode = mode;
				break;
				
			case Configuration.ORIENTATION_PORTRAIT:
//				mPortraitVideoMode = mode;
				break;
		}
//		mVideoView.setVideoMode(orientation, mode);
	}
	
	
	/**
	 * show ad with given parameters.
	 * @param gcd : goods code
	 * @param mcd : media code
	 * @param pcd : page code
	 * @param scd : screen code
	 * @param ccd : category code
	 * @return : -1 returns when any parameter is null or 0 length. otherwise returns 0.
	 */
	
	public int showAd(String gcd, String mcd, String pcd, String scd, String ccd) {
		if(gcd == null || gcd.equals("") || mcd == null || mcd.equals("") || pcd == null || pcd.equals("") || scd == null || scd.equals("") || ccd == null || ccd.equals("")) {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			destroy();
			return -1;
		}
		
		mAdInfoParameter = getAdInfoParameter(gcd, mcd, pcd, scd, ccd);
		if(mAdInfoParameter == null) {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			destroy();
			return -1;
		}
		
		showProgress();
		mAdinfoRequestUrl = (mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL);
		mConnectionManager.sendRequest(REQUEST_AD_INFOS, mAdinfoRequestUrl, mAdInfoParameter);
		
		if(mErrorHandler.isFailedWorkAvailable()) {
			new Handler().postDelayed(new Runnable() {

				@Override
				public void run() {
					mErrorHandler.sendFailedRequest();
				}
				
			}, 1000);
			
		}
		return 0;
	}
	
	public void setDialogMarginRate(int marginRate) {
		mDialogMarginRate = marginRate;
	}
	
	public void showTestAd(String url) {
		showProgress();
		mConnectionManager.sendRequest(REQUEST_AD_INFOS, url, null);
	}
	
	private JSONObject getAdInfoParameter(String gcd, String mcd, String pcd, String scd, String ccd) {
		String uid = CommonUtils.getStringPreference(mContext, DawinConfig.KEY_UID);
		
		JSONObject result = new JSONObject();
		try {
			result.put("gcd", gcd);
			result.put("mcd", mcd);
			result.put("pcd", pcd);
			result.put("scd", scd);
			result.put("ccd", ccd);
			// 20130731 버전코드 추가함.
			result.put("ver", "1.0");
			// 20131125 queryString 뒤에 UID를 붙여서 요청보내는 작업 추가함(preferences에 저장된 UID 이용)
			if(uid != null && !uid.equals("")) {
				result.put("uid", uid);
			}
			
		} catch(JSONException e) {
			result = null;
		}
		
		return result;
	}
	
	public int getCurrentState() {
		return mVideoPlayer.getCurrentState();
	}
	
	
	private void prepareVideo() {
		if(mAdInfos == null) {
			mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			return;
		}
		this.setVisibility(View.VISIBLE);
		mMediaController = new MediaController(mContext);
		mMediaController.setAnchorView(mVideoPlayer);
//		mVideoView.setMediaController(mMediaController);
		
		if(mAdInfos.getMediaFileUrl() == null) {
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			}
		}
		mVideoPlayer.setVideoURI(mAdInfos.getMediaFileUrl());
		mVideoPlayer.requestFocus();
		mVideoPlayer.setOnPreparedListener(new BKVideoPlayer.OnPreparedListener() {
			
			@Override
			public void onPrepared(MediaPlayer mp) {
				if(mAdInfos == null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
					return;
				}
				showProgress();
				initTimers();
				BKLog.d("media width : " + mp.getVideoWidth() + ", media height : " + mp.getVideoHeight());
				BKLog.d("greatest common measure : " + CommonUtils.getGreatestCommonMeasure(mp.getVideoWidth(), mp.getVideoHeight()));
				
				int duration = mp.getDuration();
				
				if(duration < 16000) {
					// smaller than 16000 -> it's 15sec ad
					BKLog.e("============================== 15sec ad ================================");
					mIsQuarterMinAd = true;
				} else {
					BKLog.e("============================== other sec ad ================================");
					mIsQuarterMinAd = false;
				}
				
				try {
					if(mAdInfos.getChargeTime() > duration) {
						mChargeTime = duration - 500;
					} else {
						mChargeTime = mAdInfos.getChargeTime();
					}
					
					BKLog.e("Duration : " + duration + ", chargetime : " + mChargeTime + "real chargetime : " + mAdInfos.getChargeTime());
				} catch(NumberFormatException e) {
					mChargeTime = mAdInfos.getChargeTime() - 1000;
				}
				
				
				
				if(mAdInfos != null) {
					BKLog.i("------------- Start new video");
					mLastSendedTag = 0;
					mAdDuration = mp.getDuration();
					mQuarter = mAdInfos.getQuarterTime(1);
					mQuarter2 = mAdInfos.getQuarterTime(2);
					mQuarter3 = mAdInfos.getQuarterTime(3);
//					setVideoPlayerSize();
					mp.start();
					BKLog.e("Duration : " + mp.getDuration());
					if(!mSkipButton.isShown()) {
						BKLog.i("::> BKSkipTimer start");
						int skipTimerDelay = (int) (mAdInfos.getIconShowTime(AdInfos.SKIP) * 0.8);
						startTimer(SKIP_TIMER, skipTimerDelay, mTimerPeriod);
					}
				}
				
				if(mPreparedListener != null) {
					mPreparedListener.onPrepared();
				}
			}
		});
		
	}
	
	public void onConfigurationChanged() {
		int orientation;
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
			orientation = Configuration.ORIENTATION_PORTRAIT;
		} else {
			orientation = Configuration.ORIENTATION_LANDSCAPE;
		}
		
		mVideoPlayer.refreshDrawableState();
	}
	
	
	private void showProgress() {
		lockClickEvents(false);
		mProgress.setVisibility(View.VISIBLE);
	}
	
	private void hideProgress() {
		lockClickEvents(true);
		mProgress.setVisibility(View.GONE);
	}
	
	
	/**
	 * lock clickable views
	 * @param isLock : false to lock buttons
	 */
	private void lockClickEvents(boolean isLock) {
		mVideoLayout.setClickable(isLock);
		mFacebookButton.setClickable(isLock);
		mTwitterButton.setClickable(isLock);
		mMe2DayButton.setClickable(isLock);
		mSkipButton.setClickable(isLock);
		mEventButton.setClickable(isLock);
		mCallButton.setClickable(isLock);
		mMapButton.setClickable(isLock);
		mDownloadButton.setClickable(isLock);
	}
	
	
	
	private void initializeVideoView() {
		destroy();
		System.gc();
		// remove or stop schedulers
		cancelAllTimer();
		mCurrentCallState = CALL_STATE_IDLE;
		mIsClickviewerShown = false;
		mIsOnPauseCalled = false;
		// remove ad informations
		mAdInfos = null;
		// initialize tag
		mIsStartTagSended = false;
		// initialize videoview click
		mIsVideoClickProcessing = false;
		
		DawinAdPlayer.this.removeAllViews();
		setViews();
	}
	
	private void checkIconImage(int actionMode) {
		if(mAdInfos == null) {
			return;
		}
		switch(actionMode) {
			case AdInfos.ACTION_MODE_SNS:
				if(mAdInfos.getIconUrl(AdInfos.FACEBOOK) != null && mAdInfos.isIconShowDirectly(AdInfos.FACEBOOK)) {
					mImageDownloader.download(DawinConfig.IMG_FACEBOOK_URL, mFacebookButton, mAdInfos.isIconShowDirectly(AdInfos.FACEBOOK));
				}
				
				if(mAdInfos.getIconUrl(AdInfos.TWITTER) != null) {
					mImageDownloader.download(DawinConfig.IMG_TWITTER_URL, mTwitterButton, mAdInfos.isIconShowDirectly(AdInfos.TWITTER));
				}
				
				if(mAdInfos.getIconUrl(AdInfos.ME2DAY) != null) {
					mImageDownloader.download(DawinConfig.IMG_ME2DAY_URL, mMe2DayButton, mAdInfos.isIconShowDirectly(AdInfos.ME2DAY));
				}
				break;
				
			case AdInfos.ACTION_MODE_CALL:
				if(mAdInfos.getIconUrl(AdInfos.CALL) != null) {
					mImageDownloader.download(DawinConfig.IMG_CALL_URL, mCallButton, mAdInfos.isIconShowDirectly(AdInfos.CALL));
				}
				break;
				
			case AdInfos.ACTION_MODE_DOWNLOAD:
				if(mAdInfos.getIconUrl(AdInfos.DOWNLOAD) != null) {
					mImageDownloader.download(DawinConfig.IMG_DOWN_URL, mDownloadButton, mAdInfos.isIconShowDirectly(AdInfos.DOWNLOAD));
				}
				break;
				
			case AdInfos.ACTION_MODE_EVENT:
				if(mAdInfos.getIconUrl(AdInfos.EVENT) != null) {
					mImageDownloader.download(DawinConfig.IMG_EVENT_URL, mEventButton, mAdInfos.isIconShowDirectly(AdInfos.EVENT));
				}
				break;
				
			case AdInfos.ACTION_MODE_MAP:
				if(mAdInfos.getIconUrl(AdInfos.MAP) != null) {
					mImageDownloader.download(DawinConfig.IMG_MAP_URL, mMapButton, mAdInfos.isIconShowDirectly(AdInfos.MAP));
				}
				break;
				
		}
		
//		if(mAdInfos.getIconUrl(AdInfos.SKIP) != null) {
//			mImageDownloader.download(DawinConfig.IMG_SKIP_URL, mSkipButton, false);
//		}
		
		mImageDownloader.download(DawinConfig.IMG_SKIP_URL, mSkipButton, false);
		// TODO : 스킵버튼 이전에 나오는 버튼에 대해서 처리함.
		mImageDownloader.download(DawinConfig.IMG_SKIP_DESCRIPTION_URL, mSkipDescriptionButton, true);
		
	}
	
	private void showActionLayout() {
		if(mAdInfos != null) {
			switch(mAdInfos.getActionMode()) {
				case AdInfos.ACTION_MODE_SNS:
					mSnsLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_CALL:
					mCallLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_DOWNLOAD:
					mDownloadLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_EVENT:
					mEventLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_MAP:
					mMapLayout.setVisibility(View.VISIBLE);
					break;
			}
		}
		mSkipLayout.setVisibility(View.VISIBLE);
	}
	
	
	public int destroy() {
		cancelAllTimer();
		if(mVideoPlayer != null) {
			mVideoPlayer.release();
		}
		this.removeAllViews();
		System.gc();
		return 0;
	}
	
	
	private void showCallDialog(String phoneNumber) {
		if(mAdInfos == null) {
			mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			return;
		}
		
		// 20130624 추가. 전화 버튼을 눌렀을 때 요청 보내는 걸로 수정
		final String callTracking = mAdInfos.getTrackingUrl(IconInfoParser.ICON_CALL) + getActionButtonParameter();
		hideProgress();
		initializeVideoView();
		final String num = phoneNumber;
		if(CommonUtils.canMakeCall(mContext)) {
			AlertDialog dialog = CommonUtils.getAlertDialog(mContext, null, phoneNumber, "취소", "통화", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_INCOMING_CALL);
					}
				}
			} , new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					mCurrentCallState = CALL_STATE_OUTGOING;
					mConnectionManager.sendRequest(REQUEST_PHONE_CLICK, callTracking, null);
					CommonUtils.callTo(mContext, num);
				}
			});
			dialog.show();
			TextView msg = (TextView) dialog.findViewById(android.R.id.message);
			msg.setGravity(Gravity.CENTER);
			
		} else {
			AlertDialog dialog = CommonUtils.getAlertDialog(mContext, null, "전화 기능을 이용할 수 없는 상태입니다.", "확인", null, new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_INCOMING_CALL);
					}
				}
			}, null);
			dialog.show();
			TextView msg = (TextView) dialog.findViewById(android.R.id.message);
			msg.setGravity(Gravity.CENTER);
		}
	}
	
	
	/**
	 * 화면 클릭 이벤트 등 뷰에 관련된 이벤트 발생이 필요한 경우 반환함.
	 * @return View : VideoView를 담고있는 컨테이너.
	 */
	public View getScreenContainerView() {
		return mVideoLayout;
	}
	
	
	public void setOnPlayFinishListener(OnPlayFinishListener listener) {
		mPlayFinishListener = listener;
	}
	
	public void setOnErrorListener(OnErrorListener listener) {
		mErrorListener = listener;
	}
	
	public void setOnPreparedListener(OnPreparedListener listener) {
		mPreparedListener = listener;
	}
	
	/*****************************************************************************/
	/*************************test code!!!!!!!!!!!!!!!!***************************/
	/*****************************************************************************/
	public String getXmlString() {
		return xmlString;
	}
	/*****************************************************************************/
	/*************************test code!!!!!!!!!!!!!!!!***************************/
	/*****************************************************************************/
	
	@Override
	public void onRequestFinished(int whichRequest, HttpResponse result, String extractString) {
		BKLog.i("Request success!!!!!!!");
		switch(whichRequest) {
			case REQUEST_AD_INFOS:
				BKLog.i("Request ad info receive success!!");
				// 새로 정보를 받은 경우 과금테그 flag 초기화함.
				mIsChargeTagSendSucceed = false;
				xmlString = extractString;
				BKAdInfoParser parser = new BKAdInfoParser(extractString);
				mAdInfos = parser.parse();
				if(mAdInfos != null) {
					String adId = mAdInfos.getAdId();
					
					if(adId != null && Integer.parseInt(adId) != DawinConfig.SERVER_MSG_NO_APPLICABLE_AD) {
						
						
						BKLog.e("Action mode : " + mAdInfos.getActionMode());
						
						checkIconImage(mAdInfos.getActionMode());
						
						prepareVideo();
					} else {
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NO_APPLICABLE_AD);
						}
						hideProgress();
						DawinAdPlayer.this.setVisibility(View.GONE);
					}
				}
				
				
				break;
				
			case REQUEST_START:
				BKLog.i("Start tag send success");
				break;
				
			case REQUEST_QUARTER:
				BKLog.i("Quarter tag send success");
				break;
				
			case REQUEST_QUEARTER2:
				BKLog.i("Quarter2 tag send success");
				break;
				
			case REQUEST_QUEARTER3:
				BKLog.i("Quarter3 tag send success");
				break;
				
			case REQUEST_FINISHED:
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
				initializeVideoView();
				BKLog.i("Finish tag send success");
				break;
				
			case REQUEST_SKIP:
				BKLog.i("Skip tag send success");
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SKIP);
				}
				initializeVideoView();
				break;
				
			case REQUEST_ERROR:
				BKLog.i("Error tag send success");
				break;
				
			case REQUEST_CHARGE:
				mIsChargeTagSendSucceed = true;
				if(mIsQuarterMinAd && mAdInfos != null) {
					mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
				} else {
					hideProgress();
					BKLog.e("====================================> Charge tag send success");
				}
				
				break;
				
			case REQUEST_PHONE_CLICK:
				BKLog.i("PhoneTag send success");
				break;
				
			case REQUEST_SEND_TAG:
				BKLog.i("tag send success");
				break;
			
		}
	}

	@Override
	public void onRequestError(int whichRequest, int errorCode, String message) {
		BKLog.e("Request error!!!!!!!");
		BKLog.e("Error code : " + errorCode + ", request : " + whichRequest);
		
		switch(whichRequest) {
			case REQUEST_AD_INFOS:
				if(errorCode == BKConnectionManager.NETWORK_DISCONNECTED) {
//					Toast.makeText(mContext, "네트워크가 끊어졌습니다. 상태 확인 후 다시 이용해 주세요", Toast.LENGTH_SHORT).show();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NETWORK_DISCONNECTED);
					}
					initializeVideoView();
				} else {
					if(mAdInfoRetryCount >= MAX_RETRY_COUNT) {
						// finish retry. 뷰 종료 또는 에러처리
						hideProgress();
//						Toast.makeText(mContext, "광고 정보 수신 실패", Toast.LENGTH_SHORT).show();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AD_INFO_RECEIVE_FAIL);
						}
						// 광고정보요청 실패 로그 서버전송.
						String errorUrl = (DawinConfig.isDebugMode?ADINFO_ERROR_LOG_DEV:ADINFO_ERROR_LOG_REL) + mAdinfoRequestUrl;
						mErrorHandler.sendErrorTag(errorUrl);
					} else {
						mAdInfoRetryCount++;
						mConnectionManager.sendRequest(REQUEST_AD_INFOS, mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL, mAdInfoParameter);
						BKLog.e("Ad info receive failed. retry..( " + mAdInfoRetryCount + ")");
					}
				}
				break;
				
			case REQUEST_START:
				// do nothing
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=2");
				}
				
				break;
				
			case REQUEST_QUARTER:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=3");
				}
				// do nothing
				break;
				
			case REQUEST_QUEARTER2:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=4");
				}
				break;
				
			case REQUEST_QUEARTER3:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=5");
				}
				break;
				
			case REQUEST_FINISHED:
				// 정상종료처럼 바로 진행
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=6");
				}
				initializeVideoView();
				break;
				
			case REQUEST_SKIP:
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SKIP);
				}
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=7");
				}
				initializeVideoView();
				break;
				
			case REQUEST_ERROR:
				// do nothing
				break;
				
			case REQUEST_CHARGE:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=8");
				}
				handleChargeRequestError(whichRequest);
				break;
				
			case REQUEST_PHONE_CLICK:
				
				break;
				
			case REQUEST_SEND_TAG:
				BKLog.i("tag send error");
				break;
			
		}
		
	}
	
	private boolean handleChargeRequestError(int currRequest) {
		if(mChargeTagRetryCount >= MAX_RETRY_COUNT) {
			// finish retry. save failed list.
			if(mAdInfos != null) {
				mErrorHandler.saveFailedWork(mAdInfos.getChargeTag());
			}
			if(mIsQuarterMinAd && mAdInfos != null) {
				mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
			} else {
				hideProgress();
				initializeVideoView();
			}
			
			return true;
		} else {
			mChargeTagRetryCount++;
			if(mAdInfos != null) {
				mConnectionManager.sendRequest(currRequest, mAdInfos.getEndTag(), null);
			}
			BKLog.e("Ad info receive failed. retry..( " + mChargeTagRetryCount + ")");
			return false;
		}
	}
	
	public void onPause() {
		cancelAllTimer();
		destroy();
	}
	
	public void onDestroy() {
		cancelAllTimer();
		destroy();
	}
	
	public void onBackPressed() {
		cancelAllTimer();
		destroy();
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BACK_KEY_PRESSED);
		}
	}

	@Override
	public void onDialogShown() {
	}
	
	@Override
	public void onDialogDismissed() {
		hideProgress();
	}
	

}
